package com.github.freegeese.maven.plugin.autocode.metadata;

import com.github.freegeese.maven.plugin.autocode.Helper;
import com.github.freegeese.maven.plugin.autocode.configuration.ModelType;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by Administrator on 2017/3/29.
 */
public class Table {
    private String tableCat;
    private String tableSchem;
    private String tableName;
    private String tableType;
    private String remarks;
    private String typeCat;
    private String typeSchem;
    private String typeName;
    private String selfReferencingColName;
    private List<Column> columns;
    private List<PrimaryKey> primaryKeys;
    // 自定义字段----------------------------------
    // 模型名称
    private String modelName;
    // 主键列
    private Column idColumn;
    // 导入列
    private List<String> includeColumns;
    // 排除列
    private List<String> excludeColumns;
    // 最终过滤后的列
    private List<Column> filteredColumns;
    // 模型类型
    private ModelType modelType;
    // 视图
    private String viewUrl;
    private String viewName;

    public Table() {
    }

    public Table(String tableCat, String tableSchem, String tableName, String tableType, String remarks, String typeCat, String typeSchem, String typeName, String selfReferencingColName) {
        this.tableCat = tableCat;
        this.tableSchem = tableSchem;
        this.tableName = tableName;
        this.tableType = tableType;
        this.remarks = remarks;
        this.typeCat = typeCat;
        this.typeSchem = typeSchem;
        this.typeName = typeName;
        this.selfReferencingColName = selfReferencingColName;
    }

    public String getTableCat() {
        return tableCat;
    }

    public void setTableCat(String tableCat) {
        this.tableCat = tableCat;
    }

    public String getTableSchem() {
        return tableSchem;
    }

    public void setTableSchem(String tableSchem) {
        this.tableSchem = tableSchem;
    }

    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public String getTableType() {
        return tableType;
    }

    public void setTableType(String tableType) {
        this.tableType = tableType;
    }

    public String getRemarks() {
        return remarks;
    }

    public void setRemarks(String remarks) {
        this.remarks = remarks;
    }

    public String getTypeCat() {
        return typeCat;
    }

    public void setTypeCat(String typeCat) {
        this.typeCat = typeCat;
    }

    public String getTypeSchem() {
        return typeSchem;
    }

    public void setTypeSchem(String typeSchem) {
        this.typeSchem = typeSchem;
    }

    public String getTypeName() {
        return typeName;
    }

    public void setTypeName(String typeName) {
        this.typeName = typeName;
    }

    public String getSelfReferencingColName() {
        return selfReferencingColName;
    }

    public void setSelfReferencingColName(String selfReferencingColName) {
        this.selfReferencingColName = selfReferencingColName;
    }

    public void setColumns(List<Column> columns) {
        this.columns = columns;
    }

    public List<Column> getColumns() {
        return columns;
    }

    public List<PrimaryKey> getPrimaryKeys() {
        return primaryKeys;
    }

    public void setPrimaryKeys(List<PrimaryKey> primaryKeys) {
        this.primaryKeys = primaryKeys;
    }

    public String getModelName() {
        return modelName;
    }

    public void setModelName(String modelName) {
        this.modelName = modelName;
    }

    public List<String> getIncludeColumns() {
        return includeColumns;
    }

    public void setIncludeColumns(List<String> includeColumns) {
        this.includeColumns = includeColumns;
    }

    public List<String> getExcludeColumns() {
        return excludeColumns;
    }

    public void setExcludeColumns(List<String> excludeColumns) {
        this.excludeColumns = excludeColumns;
    }

    public Column getIdColumn() {
        return idColumn;
    }

    public void setIdColumn(Column idColumn) {
        this.idColumn = idColumn;
    }

    public List<Column> getFilteredColumns() {
        return filteredColumns;
    }

    public void setFilteredColumns(List<Column> filteredColumns) {
        this.filteredColumns = filteredColumns;
    }

    public ModelType getModelType() {
        return modelType;
    }

    public void setModelType(ModelType modelType) {
        this.modelType = modelType;
    }

    public String getViewUrl() {
        if (null != viewUrl) {
            return viewUrl;
        }
        StringBuilder replaced = new StringBuilder();
        Matcher m = Pattern.compile("[A-Z][a-z]*").matcher(getModelName());
        while (m.find()) {
            replaced.append(m.group().toLowerCase()).append("/");
        }
        return replaced.toString().replaceAll("^/|/$", "");
    }

    public void setViewUrl(String viewUrl) {
        this.viewUrl = viewUrl;
    }

    public String getViewName() {
        if (null != viewName) {
            return viewName;
        }
        String modelName = getModelName();
        return modelName.substring(0, 1).toLowerCase().concat(modelName.substring(1));
    }

    public void setViewName(String viewName) {
        this.viewName = viewName;
    }

    // 针对于 Model ------------------------------
    public Set<String> getModelImports() {
        Set<String> returnValue = new LinkedHashSet<>();
        for (Column column : getFilteredColumns()) {
            if (!Helper.isLangPackageClass(column.getJavaType())) {
                returnValue.add(column.getJavaType().getName());
            }
        }
        return returnValue;
    }


    // 针对于 Mybatis Mapper ------------------------------
    public String getBaseColumnList() {
        StringBuilder columns = new StringBuilder();
        for (int i = 0; i < this.filteredColumns.size(); i++) {
            columns.append(this.filteredColumns.get(i).getColumnName());
            if (i < this.filteredColumns.size() - 1) {
                columns.append(", ");
            }
        }
        return columns.toString();
    }

    public String getInsertColumnList() {
        StringBuilder columns = new StringBuilder();
        for (int i = 0; i < this.filteredColumns.size(); i++) {
            Column column = this.filteredColumns.get(i);
            if (!column.isAutoincrement()) {
                columns.append(column.getColumnName());
                if (i < this.filteredColumns.size() - 1) {
                    columns.append(", ");
                }
            }
        }
        return columns.toString();
    }

    public List<Column> getInsertSelectiveColumnList() {
        List<Column> columns = new ArrayList<>();
        for (int i = 0; i < this.filteredColumns.size(); i++) {
            Column column = this.filteredColumns.get(i);
            if (!column.isAutoincrement()) {
                columns.add(column);
            }
        }
        return columns;
    }

    public String getInsertValues() {
        StringBuilder columns = new StringBuilder();
        for (int i = 0; i < this.filteredColumns.size(); i++) {
            Column column = this.filteredColumns.get(i);
            if (!column.isAutoincrement()) {
                columns.append("#{" + column.getProperty() + ",jdbcType=" + column.getJdbcType() + "}");
                if (i < this.filteredColumns.size() - 1) {
                    columns.append(", ");
                }
            }
        }
        return columns.toString();
    }

    public List<Column> getColumnsWithoutPrimaryKey() {
        List<Column> columns = new ArrayList<>();
        for (int i = 0; i < this.filteredColumns.size(); i++) {
            Column column = this.filteredColumns.get(i);
            if (!column.getColumnName().equals(idColumn.getColumnName())) {
                columns.add(column);
            }
        }
        return columns;
    }
}
